package com.leetcode;

import java.util.Arrays;

public class Leetcode322 {

    //solution 1：动态规划
    /*
    *   我们可以想象成爬楼梯的情况：请参考Leetcode070
    *   状态定义：dp[i]：跑到当前位置最小的步数
    *   状态转移：dp[i-coins[j]：跑到 i 位置的前一个位置的最小步数，coins[j]表示遍历所有可能的情况
    *   最终 dp[i] = Min{dp[i-coins[j]} + 1
    *   时间复杂度O(amount*coins.length)
    *   空间复杂度O(amount)
     */
    public int coinChange(int[] coins, int amount) {
        int max = Integer.MAX_VALUE - 1;
        int[] dp = new int[amount + 1];
        //dp[0]:金额为0不能由硬币组成;max:非法值,表示某一个金额不能由其他硬币组成
        Arrays.fill(dp, max);
        dp[0] = 0;

        //0->amount遍历
        for (int i = 0; i <= amount; i++) {
            //0-> j 遍历coin里面的数值
            for (int j = 0; j < coins.length; j++) {
                //只有 coin数值小于i，才有可能作为它的前一次的位置
                if (i >= coins[j]) {
                    //当前位置的最小步数一个 = 前一个位置的最小步数 + 1
                    dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
                }
            }
        }

        //最后的位置出现max值，代表它不能够由coins的数值拼凑而成
        return dp[amount] == max ? -1 : dp[amount];
    }

    public static void main(String[] args) {
        int[] coins = {1, 2, 5};
        Leetcode322 leetcode = new Leetcode322();
        System.out.println(leetcode.coinChange(coins, 11));
    }
}
